package utils;

import java.lang.reflect.Field;
import java.util.*;

import dto.http.AniCookieDto;

import org.apache.commons.lang3.StringUtils;
import play.mvc.Http.*;
import services.exception.AniAuthException;
import services.exception.AniDataException;


public class MVCUtils {

	//cookie
	public static Integer COOKIE_MAX_AGE = 86400 * 14;
	
	public static String USER_KEY = "aniUserEmail";

	public static HashMap<String, String> getRequestArgs(play.mvc.Http.Request request){
		Map<String, String[]> reqArgs = request.body().asFormUrlEncoded();
		
		HashMap<String, String> resultMap = new HashMap<String, String>();
//		System.out.println(reqArgs.size());
		for(String oneKey: reqArgs.keySet()){
			resultMap.put(oneKey, reqArgs.get(oneKey)[0]);
		}
		return resultMap;
	}
	
	public static <T> T getRequestDTO(play.mvc.Http.Request request, Class<T> dtoClass){
		return request.body().as(dtoClass);
	}
	
	public static void pushClientCookie(AniCookieDto oneAniCookie){
		Context context = Context.current();
		if(oneAniCookie.lifetime <= 0 || oneAniCookie.lifetime == null){
			context.response().setCookie(oneAniCookie.key, oneAniCookie.value);
		}else{
			context.response().setCookie(oneAniCookie.key, oneAniCookie.value, oneAniCookie.lifetime);
		}
	}
	
	public static String pullClientCookie(String key){
        Context context = Context.current();
        return pullClientCookie(context, key);
    }
    public static String pullClientCookie(Context context, String key){
        try{
            return context.request().cookies().get(key).value();
        } catch (Exception e){
            throw new AniDataException("COOKIE_NOT_EXISTS");
        }
    }
	//user info cookie
	public static String pullLocalUserKeyFromCookie(){
        try{
            return pullClientCookie(USER_KEY);
        }catch(Exception e){
            throw new AniAuthException("HAVE_NOT_LOGIN");
        }
	}
    public static String pullLocalUserKey(Context context){
        return pullClientCookie(context, USER_KEY);
    }
     // --- Form utils
    public static void verifyRequiredElements(Map<String, String> fieldsValue, String[] requiredFieldKeys){
        StringBuilder errorMsg = new StringBuilder();
        for(String oneKey:requiredFieldKeys){
            if(!isFormFieldIgnored(fieldsValue.get(oneKey))){
                errorMsg.append(" [" + oneKey + "] ");
            }
        }
        if(errorMsg.length() > 0){
            throw new AniAuthException(
                    "REQUIRED_FIELDS_EMPTY: " +
                    errorMsg.toString()
            );
        }
    }
    public static void verifyRequiredElementsInObject(Object oneObj, String[] requiredFieldsName){
        StringBuilder errorMsg = new StringBuilder();
        for(String oneKey:requiredFieldsName){
            Object oneFieldValue = null;
            try{
                oneFieldValue = oneObj.getClass().getField(oneKey).get(oneObj);
            }catch(Exception e){
                throw new AniDataException("FIELD_NOT_EXISTS");
            }
            if(!isFormFieldIgnored(oneFieldValue)){
                errorMsg.append(" [" + oneKey + "] ");
            }
        }
        if(errorMsg.length() > 0){
            throw new AniAuthException(
                    "REQUIRED_FIELDS_EMPTY: " +
                            errorMsg.toString()
            );
        }
    }
    private static Boolean isFormFieldIgnored(Object oneArg){
        if(isFieldEmpty(oneArg) || oneArg.equals("0")){
            return false;
        }
        return true;
    }
    public static Boolean isFieldEmpty(Object oneField){
        if(oneField == null){
            return true;
        }
        if(oneField instanceof String){
            return StringUtils.isEmpty(String.valueOf(oneField));
        }else if(oneField instanceof List){
            return ((List) oneField).size() < 1;
        }else{
            return false;
        }
    }
    public static List<Long> generateIdListFromStrArray(String[] fromArray){
        List<Long> resultIdList = new ArrayList<Long>();
        for(String oneArrElem: fromArray){
            resultIdList.add(Long.parseLong(oneArrElem));
        }
        return resultIdList;
    }
    public static String getConfig(String configKey){
        return play.Play.application().configuration().getString(configKey);
    }
    public static String deleteUrlParams(String srcUrl){
        if(srcUrl.contains("?")){
            return srcUrl.substring(0, srcUrl.indexOf('?'));
        }
        return srcUrl;
    }
}
